module Ministerio (Ministerio, agregarHotelM, secretariasM, registroM, nuevoM, cadenasDeHotelesM, cadenasAmarretasM, fusionAutorizadaM, sinLCDParaTodos) where

import Tipos
import Reserva
import Habitacion
import Hotel

data Ministerio = REG Provincia Hotel Ministerio | MT [Provincia] deriving (Show)

nuevoM :: [Provincia] -> Ministerio
nuevoM ps = MT ps

secretariasM :: Ministerio -> [Provincia]
secretariasM (MT ps) = ps
secretariasM (REG _ _ m) = secretariasM m

registroM :: Ministerio -> Provincia -> [Hotel]
registroM (MT pv) p = []
registroM (REG prov ht m) p
  | prov == p = ht:(registroM m p)
  | otherwise = registroM m p

cadenasDeHotelesM :: Ministerio -> [[Hotel]]
cadenasDeHotelesM (MT ps) = [[]]
cadenasDeHotelesM (REG p h m) = insertarHotel h (cadenasDeHotelesM m)

agregarHotelM :: Ministerio -> Hotel -> Provincia -> Ministerio
agregarHotelM m h p = REG p h m 

fusionAutorizadaM :: Ministerio -> Cadena -> Cadena -> Ministerio
fusionAutorizadaM (MT ps) _ _ = MT ps
fusionAutorizadaM (REG p h m) c1 c2
  | cadenaH h == c2 = REG p (venderH h c1) (fusionAutorizadaM m c1 c2)
  | otherwise = REG p h (fusionAutorizadaM m c1 c2)

cadenasAmarretasM:: Ministerio -> [Cadena]
cadenasAmarretasM m = sacarRepes(cadenasAux m m)
  
sinLCDParaTodos :: Ministerio -> (Int, Ministerio)
sinLCDParaTodos m = ((cantLCDs m), (ministerioSinLCDs m))

----------------
-- Auxiliares --
---------------- 

-- cadenasDeHotelesM --

insertarHotel :: Hotel -> [[Hotel]] -> [[Hotel]]
insertarHotel h [] = [[h]]
insertarHotel h [[]] = [[h]]
insertarHotel h (x:[])
  | cadenaH (x !! 0) == cadenaH h = [h:x]
  | otherwise = [x, [h]]
insertarHotel h (x:xs)
  | cadenaH (x !! 0) == cadenaH h = (h:x):xs
  | otherwise = x : insertarHotel h xs

-- sinLCDParaTodos --

ministerioSinLCDs :: Ministerio -> Ministerio
ministerioSinLCDs (MT ps) = MT ps
ministerioSinLCDs (REG p h m) = (REG p (dameHotelSinLCD h) (ministerioSinLCDs m))

dameHotelSinLCD :: Hotel -> Hotel
dameHotelSinLCD h = nuevoH (nombreH h) (cadenaH h) (habitacionesSinLCD (habitacionesH h)) (tipoHabXDinero h [Simple, Doble, Triple, Cuadruple]) (accesorioXDinero h [Jacuzzi, LCD, PS3, DVD, Pelotero, Inflable])

habitacionesSinLCD :: [Habitacion] -> [Habitacion]
habitacionesSinLCD []= []
habitacionesSinLCD (h:hs) = (nuevaH (numeroH h) (tipoH h) (sacarLCD (accesoriosH h))):(habitacionesSinLCD hs)

sacarLCD :: [Accesorio] -> [Accesorio]
sacarLCD [] = []
sacarLCD (a:[])
	| a == LCD = []
	| otherwise = [a]
sacarLCD (x:xs)
	| x == LCD = sacarLCD xs
	| otherwise = x:(sacarLCD xs)

tipoHabXDinero:: Hotel -> [TipoHabitacion] -> [(TipoHabitacion, Dinero)]
tipoHabXDinero h [] = []
tipoHabXDinero h (t:ts)
       |tarifaXDiaH h t==0 = tipoHabXDinero h ts
       |otherwise= (t, tarifaXDiaH h t):tipoHabXDinero h ts

accesorioXDinero :: Hotel -> [Accesorio] -> [(Accesorio, Dinero)]	
accesorioXDinero h [] = []
accesorioXDinero h (a:as)
     |precioAccesorioH h a==0 = accesorioXDinero h as
     |otherwise= (a, precioAccesorioH h a):(accesorioXDinero h as)

cantLCDs :: Ministerio -> Int
cantLCDs (MT _) = 0
cantLCDs (REG p h m) = cantLCDsHotel h + cantLCDs m

cantLCDsHotel :: Hotel -> Int
cantLCDsHotel h = cantLCDsHabitaciones (habitacionesH h)

cantLCDsHabitaciones :: [Habitacion] -> Int
cantLCDsHabitaciones [] = 0
cantLCDsHabitaciones (h:hs)
	| LCD `elem` accesoriosH h = 1 + cantLCDsHabitaciones hs
	| otherwise = cantLCDsHabitaciones hs

-- cadenasAmarretas --

cadenasAux :: Ministerio -> Ministerio -> [Cadena]
cadenasAux (MT _ ) y = []
cadenasAux (REG p h m) y
    |estaEnMenos y (cantProv y (cadenaH h)) = (cadenaH h):(cadenasAux m y)
    |otherwise = cadenasAux m y

estaEnMenos ::Ministerio -> Int -> Bool
estaEnMenos (MT _ ) i = True
estaEnMenos (REG p h m) i
        |(cantProv (REG p h m) (cadenaH h)) < i = False
        |otherwise = estaEnMenos m i

sacarRepes:: [Cadena] -> [Cadena]
sacarRepes [] = []
sacarRepes (x:xs)
       |x `elem` xs = sacarRepes xs
       |otherwise = x:sacarRepes xs


cantProv:: Ministerio -> Cadena -> Int
cantProv (MT _) c= 0
cantProv (REG p h m) c
        |cadenaH h == c && noCuentoDeMas m p c = 1 + cantProv m c
        |otherwise= 0 + cantProv m c

noCuentoDeMas:: Ministerio -> Provincia -> Cadena -> Bool
noCuentoDeMas (MT _) p c = True
noCuentoDeMas (REG x h m) p c
           |x == p && ((cadenaH h) == c) = False
           |otherwise= noCuentoDeMas m p c
